import numpy as np

# 定义AHP层次分析法类
class AHP:
    # 判断矩阵的重要性标度有1,3,5,7,9，倒数等
    # 传入numpy.array格式的判断矩阵
    def __init__(self, data):
        self.data = data
        # 记录变量的数量即判断矩阵的长度
        self.size = data.shape[0]
        # 初始化一致性检验RI值
        RI_value = [0, 0, 0.58, 0.90, 1.12, 1.24, 1.32, 1.41, 1.45, 1.51]
        # RI_value = [0, 0, 0.52, 0.89, 1.12, 1.26, 1.36, 1.41, 1.46, 1.49, 1.52, 1.54, 1.56, 1.58,
        #                         1.59]
        # 根据变量的数量选择RI
        self.RI = RI_value[self.size - 1]

    # 计算归一化的权重向量
    def calculate_eigen(self):
        # 计算判断矩阵的特征值与特征向量
        eigen_value, eigen_vector = np.linalg.eig(self.data)
        # 计算矩阵的最大特征值与其对应的特征向量
        max_variable = np.max(eigen_value)
        index = np.argmax(eigen_value)
        max_variable = round(max_variable.real, 4)
        max_vector = eigen_vector[:, index]
        max_vector = max_vector.real.round(4)  #
        self.max_var = max_variable
        # 计算归一化的权重向量W
        weight_vector = max_vector / sum(max_vector)
        weight_vector = weight_vector.round(4)
        # 输出结果
        print("AHP模型计算结果:\n\
        判断矩阵最大的特征值: {}\n\
        其对应的特征向量为: {}\n\
        归一化后的权重向量: {}".format(max_variable, max_vector, weight_vector))
        return max_variable, max_vector, weight_vector

    # 检验判断矩阵的一致性
    def check_consistency(self):
        # 计算判断矩阵的CI值
        CI = (self.max_var - self.size) / (self.size - 1)
        CI = round(CI, 4)
        # 输出结果
        print("\n\
        判断矩阵的CI值: {}\n\
        判断矩阵的RI值: {}".format(CI, self.RI))
        if self.size == 2:
            print("判断矩阵仅有两个变量，不存在一致性问题")
        else:
            # 计算CR值
            CR = CI / self.RI
            CR = round(CR, 4)
            if CR < 0.10:
                return print("判断矩阵的CR值{}，通过一致性检验".format(CR))
            else:
                return print("判断矩阵的CR值{}，未通过一致性检验".format(CR))


if __name__ == "__main__":
    A = np.array([
        [1, 3, 1 / 3, 5],
        [1 / 3, 1, 1 / 5, 3],
        [3, 5, 1, 7],
        [1 / 5, 1 / 3, 1 / 7, 1]
        ])
    model = AHP(A)
    mmax_variable, max_vector, weight_vector = model.calculate_eigen()
    model.check_consistency()